﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Xml.Linq;
using MediaBrowser.Entities;
using MediaBrowser.IRepository;

namespace MediaBrowser.Repository
{
    /// <summary>
    /// Classe d'accés aux données XML pour les média
    /// </summary>
    public class XmlMediaRepository : IMediaRepository
    {
        /// <summary>
        /// Retourne la Liste des média
        /// </summary>
        /// <returns></returns>
        public IEnumerable<Media> ListMediasByCategory(int idCategory)
        {
            List<Media> lResult = new List<Media>();
            XDocument xml = XDocument.Load(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\Data\Medias.xml");

            var q = from c in xml.Descendants("Media")
                    where ((int)c.Attribute("categoryId")).Equals(idCategory)
                    select new Media((int)c.Attribute("id"),
                                     (String)c.Attribute("name"),
                                     DateTime.Parse(c.Attribute("dateCreation").Value),
                                     ((String)c.Attribute("description")).Replace("  ", "").Trim(),
                                     null,
                                     (String)c.Attribute("urlImage"),
                                     (String)c.Attribute("urlContent"));

            foreach (var c in q)
            {
                if (!String.IsNullOrEmpty(c.UrlImage))
                {
                    c.UrlImage = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), c.UrlImage);
                }

                if (!String.IsNullOrEmpty(c.UrlContent))
                {
                    c.UrlContent = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), c.UrlContent);
                }

                #region on récupére tout les enfants d'un média

                var media = (from m in xml.Descendants("Media")
                             where ((int)m.Attribute("id")).Equals(c.Id)
                             select m);

                var lItem = from i in media.Descendants("MediaItem")
                            select new MediaItem((int)i.Attribute("id"),
                                             (String)i.Attribute("name"),
                                             DateTime.Parse(i.Attribute("dateCreation").Value),
                                             String.Empty,
                                             (String)i.Attribute("urlContent"));

                if ((lItem != null) && (lItem.Count() > 0))
                {
                    foreach (var im in lItem)
                    {
                        if (!String.IsNullOrEmpty(im.UrlContent))
                        {
                            im.UrlContent = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), im.UrlContent);
                        }
                        c.MediaItems.Add(im);
                    }
                }

                #endregion

                lResult.Add(c);
            }

            var qResult = from m in lResult orderby m.Name select m;

            return qResult.ToList<Media>();
        }

        /// <summary>
        /// Modification d'un média
        /// </summary>
        /// <param name="media"></param>
        /// <returns></returns>
        public bool UpdateMedia(Media media)
        {
            XDocument xml = XDocument.Load(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\Data\Medias.xml");

            var q = (from c in xml.Descendants("Media")
                     where ((int)c.Attribute("id")).Equals(media.Id)
                     select c).First();

            q.Attribute("description").Value = media.Description;
            q.Attribute("urlImage").Value = media.UrlImage;
            q.Attribute("urlContent").Value = media.UrlContent;
            q.Attribute("name").Value = media.Name;
            xml.Save(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\Data\Medias.xml");

            return true;
        }

        /// <summary>
        /// Création d'un média
        /// </summary>
        /// <param name="media"></param>
        /// <returns></returns>
        public bool CreateMedia(Media media)
        {
            XDocument xml = XDocument.Load(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\Data\Medias.xml");
            xml.Element("Medias").AddFirst(
            new XElement("Media",
            new XAttribute("id", media.Id),
            new XAttribute("name", media.Name),
            new XAttribute("categoryId", media.Category.Id),
            new XAttribute("dateCreation", media.DateCreation.ToString("dd/MM/yyyy")),
            new XAttribute("urlImage", media.UrlImage),
            new XAttribute("urlContent", media.UrlContent),
            new XAttribute("description", media.Description)));
            xml.Save(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\Data\Medias.xml");

            return true;
        }

        /// <summary>
        /// Suppression d'un média
        /// </summary>
        /// <param name="media"></param>
        /// <returns></returns>
        public bool DeleteMedia(Media media)
        {
            XDocument xml = XDocument.Load(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\Data\Medias.xml");

            var q = (from c in xml.Descendants("Media")
                     where ((int)c.Attribute("id")).Equals(media.Id)
                     select c).First();

            q.Remove();
            xml.Save(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\Data\Medias.xml");
            return true;
        }

        /// <summary>
        /// Nombre de média
        /// </summary>
        /// <returns></returns>
        public int CountMedia()
        {
            XDocument xml = XDocument.Load(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\Data\Medias.xml");
            var q = from c in xml.Descendants("Media") select (int)c.Attribute("id");
            if (q.ToList<int>().Count > 0)
            {
                return q.ToList<int>().Max();
            }
            else
            {
                return 0;
            }
        }

        /// <summary>
        /// Création d'un nouveau media Item
        /// </summary>
        /// <param name="idMedia"></param>
        /// <param name="mediaItem"></param>
        /// <returns></returns>
        public bool CreateMediaItem(int idMedia, MediaItem mediaItem)
        {
            XDocument xml = XDocument.Load(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\Data\Medias.xml");

            var q = (from c in xml.Descendants("Media")
                     where ((int)c.Attribute("id")).Equals(idMedia)
                     select c).First();


            q.AddFirst(
            new XElement("MediaItem",
            new XAttribute("id", mediaItem.Id),
            new XAttribute("name", mediaItem.Name),
            new XAttribute("dateCreation", mediaItem.DateCreation.ToString("dd/MM/yyyy")),
            new XAttribute("urlContent", mediaItem.UrlContent)));

            xml.Save(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\Data\Medias.xml");

            return true;
        }

        /// <summary>
        /// Suppression d'un média Item
        /// </summary>
        /// <param name="media"></param>
        /// <returns></returns>
        public bool DeleteMediaItem(int idMedia, MediaItem mediaItem)
        {
            XDocument xml = XDocument.Load(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\Data\Medias.xml");

            var q = (from c in xml.Descendants("Media")
                     where ((int)c.Attribute("id")).Equals(idMedia)
                     select c).First();

            var qi = (from c in q.Descendants("MediaItem")
                      where ((int)c.Attribute("id")).Equals(mediaItem.Id)
                      select c).First();

            qi.Remove();
            xml.Save(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\Data\Medias.xml");
            return true;
        }

        /// <summary>
        /// Nombre de média Item 
        /// </summary>
        /// <param name="idMedia"></param>
        /// <returns></returns>
        public int CountMediaItem(int idMedia)
        {
            XDocument xml = XDocument.Load(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\Data\Medias.xml");

            var q = (from c in xml.Descendants("Media")
                     where ((int)c.Attribute("id")).Equals(idMedia)
                     select c).First();

            var qi = from c in q.Descendants("MediaItem") select (int)c.Attribute("id");
            if (qi.ToList<int>().Count > 0)
            {
                return qi.ToList<int>().Max();
            }
            else
            {
                return 0;
            }
        }
    }
}
